﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace XmlSerialization
{
    class Program
    {
        static void Main(string[] args)
        {
            BinaryRepository<User> user = new BinaryRepository<User>();

            user.Insert(new User ("Vasia"));
            user.Insert(new User ("Sergey"));
            user.Insert(new User ("Petia"));

            user.Save();

            List<User> list = (List<User>)user.ChekOut();
            foreach (User i in list)
            {
                Console.WriteLine(i.ID + i.Name);
            }

            user.Delete(list[0]);

            user.Save();

            Console.ReadLine();
        }
    }

    public abstract class Repository<T> where T : IEntity
    {
        protected Dictionary<string, T> local = new Dictionary<string, T>();

        public void Insert(T entity)
        {
            local.Add(entity.ID, entity);
        }

        public void Update(T entity)
        {
            if (local.ContainsValue(entity))
            {
                local[entity.ID] = entity;
            }
            else
            {
                throw new ArgumentException(String.Format("Не найдено записей, содержащих объект {0}", entity.ToString()));
            }
        }

        public void Delete(T entity)
        {
            if (local.ContainsKey(entity.ID))
            {
                local.Remove(entity.ID);
            }
            else
            {
                throw new ArgumentException(String.Format("Не найдено записей, содержащих объект {0}", entity.ToString()));
            }
        }

        public T ReadByID(string id)
        {
            if (local.ContainsKey(id))
            {
                return local[id];
            }
            else
            {
                throw new ArgumentException(String.Format("Не найдено записей по id = {0}", id));
            }
        }

        public abstract List<T> ChekOut();
        public abstract void Save();

    }

    public class BinaryRepository<T> : Repository<T> where T : IEntity
    {
        public override List<T> ChekOut()
        {
            var xmlFormat = new XmlSerializer(typeof(Users<T>));
            using (Stream s = File.OpenRead("group.xml"))
            {
                var item = (Users<T>)xmlFormat.Deserialize(s);
                local.Clear();
                var temp = item.spisok;
                foreach (T i in temp)
                {
                    local.Add(i.ID, i);
                }
                return temp;
            }
        }

        public override void Save()
        {
            var xmlFormat = new XmlSerializer(typeof(Users<T>));
            using (Stream s = File.Create("group.xml"))
            {
                Users<T> users = new Users<T>();
                foreach (var i in local.Values)
                {
                    users.spisok.Add(i);
                }
                xmlFormat.Serialize(s, users);
            }
        }
    }

    [XmlRoot("пользователи")]
    public class Users<T> where T : IEntity
    {
        [XmlArray("список")]
        [XmlArrayItem("студенты")]
        public List<T> spisok = new List<T>();
    }

 //   [XmlRoot("пользователи")]
    public class User : IEntity
    {
        public String _id;
        private static Int32 id = 1000;
        [XmlAttribute("имя")]
        public String Name { get; set; }

        public User()
        {

        }

        public User(String name)
        {
            Name = name;
            _id = String.Format("id{0}", id++);
        }

        [XmlAttribute("id")]
        public string ID
        {
            get
            {
                return _id;
            }
        }
    }

    public interface IEntity
    {
        string ID { get; }
    }
}
